package com.pig4cloud.pig.village.welfare.service.impl;

import ch.qos.logback.core.pattern.ConverterUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.nacos.common.utils.ConvertUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.village.api.dto.WelfareRuleDTO;
import com.pig4cloud.pig.village.api.entity.Fund;
import com.pig4cloud.pig.village.api.entity.RewardEvent;
import com.pig4cloud.pig.village.api.entity.Welfare;
import com.pig4cloud.pig.village.api.entity.WelfareRule;
import com.pig4cloud.pig.village.api.request.WelfareRuleSearch;
import com.pig4cloud.pig.village.fund.service.IFundService;
import com.pig4cloud.pig.village.rules.service.IRuleService;
import com.pig4cloud.pig.village.sequence.service.ISequenceService;
import com.pig4cloud.pig.village.welfare.mapper.WelfareRuleMapper;
import com.pig4cloud.pig.village.welfare.service.IWelfareRuleService;
import com.pig4cloud.pig.village.welfare.service.IWelfareService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import java.time.format.DateTimeFormatter;

import static com.pig4cloud.pig.village.api.CommonConst.FLG_ONUSE;

/**
 * @author limbray.li
 * @date 2021/6/19
 */
@Service
@RequiredArgsConstructor
public class WelfareRuleServiceImpl extends ServiceImpl<WelfareRuleMapper, WelfareRule> implements IWelfareRuleService {
	@Resource
	private IFundService fundService;
	@Resource
	private IWelfareService welfareService;
	@Resource
	private IRuleService ruleService;
	@Resource
	private WelfareRuleMapper welfareRuleMapper;
	@Resource
	private ISequenceService sequenceService;

	@Override
	public IPage<WelfareRuleDTO> pageBySearch(Page page, WelfareRuleSearch request) {
		LambdaQueryWrapper<WelfareRule> query = Wrappers.lambdaQuery();
		query.eq(request.getWelfareId() != null, WelfareRule::getWelfareId, request.getWelfareId());
		query.eq(request.getFundId() != null, WelfareRule::getFundId, request.getFundId());
		query.eq(request.getYear() != null, WelfareRule::getYear, request.getYear());
		IPage<WelfareRule> pages = super.page(page, query);
		if (CollectionUtils.isEmpty(pages.getRecords())) {
			return pages.convert(e -> null);
		}
		Map<Long,Fund> fundMap = fundService.list().stream().collect(Collectors.toMap(Fund::getId, Function.identity()));
		Map<Long,Welfare> welfareMap = welfareService.list().stream().collect(Collectors.toMap(Welfare::getId, Function.identity()));
		IPage<WelfareRuleDTO> result = pages.convert(e -> {
			WelfareRuleDTO dto = new WelfareRuleDTO();
			BeanUtil.copyProperties(e, dto);
			Fund fund = fundMap.get(e.getFundId());
			Welfare welfare = welfareMap.get(e.getWelfareId());
			if (fund != null) {
				dto.setFundName(fund.getFundName());
				dto.setFundCode(fund.getFundCode());
			}
			if (welfare != null) {
				dto.setWelfareName(welfare.getWelfareName());
				dto.setWelfareCode(welfare.getWelfareCode());
			}
			return dto;
		});
		return result;
	}

	@Override
	public List<WelfareRule> listByWelfareId(Long welfareId, Integer raise, Integer timeDimension) {
		LambdaQueryWrapper<WelfareRule> query = Wrappers.lambdaQuery();
		query.eq(welfareId != null, WelfareRule::getWelfareId, welfareId);
		query.eq(raise != null, WelfareRule::getRaise, raise);
		query.eq(timeDimension != null, WelfareRule::getTimeDimension, timeDimension);
		return super.list(query);
	}

	@Override
	public Boolean updateRulesById(String rules, Long id, Long welfareId) {
		//更新规则
		LambdaUpdateWrapper<WelfareRule> update = Wrappers.lambdaUpdate();
		update.set(WelfareRule::getRules, rules);
		update.eq(WelfareRule::getId, id);
		boolean result = super.update(update);
		//查询规则(welfareId+raise+timeDimension+groupDimension+year)
		WelfareRule rule = super.getById(id);
		LambdaQueryWrapper<WelfareRule> query = Wrappers.lambdaQuery();
		query.eq(WelfareRule::getWelfareId, welfareId);
		query.eq(WelfareRule::getRaise, rule.getRaise());
		query.eq(WelfareRule::getTimeDimension, rule.getTimeDimension());
		query.eq(WelfareRule::getGroupDimension, rule.getGroupDimension());
		query.eq(WelfareRule::getYear, rule.getYear());
		List<WelfareRule> ruleList = super.list(query);
		//将规则逻辑保存到规则引擎中
		result = ruleService.saveRules(ruleList);
		return result;
	}

	@Override
	public Boolean updateRulesById(Long id) {
		//查询规则(welfareId+raise+timeDimension+groupDimension+year)
		WelfareRule rule = super.getById(id);
		LambdaQueryWrapper<WelfareRule> query = Wrappers.lambdaQuery();
		query.eq(WelfareRule::getWelfareId, rule.getWelfareId());
		query.eq(WelfareRule::getRaise, rule.getRaise());
		query.eq(WelfareRule::getTimeDimension, rule.getTimeDimension());
		query.eq(WelfareRule::getGroupDimension, rule.getGroupDimension());
		query.eq(WelfareRule::getYear, rule.getYear());
		List<WelfareRule> ruleList = super.list(query);
		//将规则逻辑保存到规则引擎中
		return ruleService.saveRules(ruleList);
	}

	@Override
	public List<WelfareRule> getAllRules() {
		return welfareRuleMapper.getAllRules();
	}

	@Override
	public List<WelfareRule> getMonthRules() {
		return welfareRuleMapper.getMonthRules();
	}

	@Override
	public List<WelfareRule> getYearRules() {
		return welfareRuleMapper.getYearRules();
	}

	@Override
	public List<WelfareRule> getBirthDayRules() {
		return welfareRuleMapper.getBirthDayRules();
	}

	@Override
	public List<WelfareRule> getSchoolRules() {
		return welfareRuleMapper.getSchoolRules();
	}

	@Override
	public List<RewardEvent> eventConvert(List<WelfareRule> rules, String scheduleCode,Integer timeDimension) {
		LocalDateTime time = LocalDateTimeUtil.now();
		Integer year = time.getYear();
		Integer month = time.getMonthValue();
		DateTimeFormatter dataFormat = DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_PATTERN);
		//rules转化为事件，此方法被定时任务调用，不会被插件拦截，需要注明租户和创建信息
		List<RewardEvent> result = rules.stream().map(e->{
			RewardEvent event = RewardEvent.builder()
					.timeDimension(timeDimension)
					.scheduleCode(scheduleCode)
					.scheduleWelfareId(e.getWelfareId())
					.year(year)
					.month(month)
					.eventNum(getEventNum())
					.eventDesc("job: "+scheduleCode)
					.eventTime(time)
					.createBy("system")
					.createTime(time)
					.delFlag(String.valueOf(FLG_ONUSE))
					.tenantId(e.getTenantId())
					.build();
			return event;
		}).collect(Collectors.toList());
		return result;
	}

	/**
	 * 获取事件编号
	 *
	 * @return
	 */
	private String getEventNum() {
		String name = DatePattern.PURE_DATE_FORMAT.format(new Date());
		return name + "-" + sequenceService.nextNum(name, 1);
	}
}
